<!-- eslint-disable no-undef -->
<!--
 * @Descripttion: 数据表格组件
 * @version: 1.10
 * @Author: sakuya
 * @Date: 2021年11月29日21:51:15
 * @LastEditors: sakuya
 * @LastEditTime: 2022年6月4日17:35:26
-->

<template>
    <!-- <el-form  :model="form" :rules="rules" ref="form">  -->
    <div class="scTable" :style="{ height: _height }" ref="scTableMain" v-loading="loading">
        <div v-if="batchEdit" class="scTable-table" :style="{ height: _table_height }">
            <el-form :model="form" :rules="rules" :style="{ height: _height }" ref="formTableRef">
                <el-table
                    v-bind="$attrs"
                    :data="form.tableData"
                    :row-key="rowKey"
                    :key="toggleIndex"
                    ref="scTable"
                    :height="height == 'auto' ? null : '100%'"
                    :size="config.size"
                    :border="config.border"
                    :stripe="config.stripe"
                    :summary-method="
						remoteSummary ? remoteSummaryMethod : summaryMethod
					"
                    @sort-change="sortChange"
                    @filter-change="filterChange"
                >
                    <slot></slot>
                    <template v-for="(item, index) in userColumn" :key="index">
                        <el-table-column
                            v-if="!item.hide && showColumn"
                            :column-key="item.prop"
                            :label="item.label"
                            :prop="item.prop"
                            :width="item.width"
                            :sortable="item.sortable"
                            :fixed="item.fixed"
                            :filters="item.filters"
                            :filter-method="
								remoteFilter || !item.filters
									? null
									: filterHandler
							"
                            :show-overflow-tooltip="item.showOverflowTooltip"
                        >
                            <template #default="scope">
                                <slot :name="item.prop" v-bind="scope">{{ scope.row[item.prop] }}</slot>
                            </template>
                        </el-table-column>
                    </template>
                    <el-table-column min-width="1"></el-table-column>
                    <template #empty>
                        <el-empty :description="emptyText" :image-size="100"></el-empty>
                    </template>
                </el-table>
            </el-form>
            <div class="scTable-page" v-if="!hidePagination || !hideDo">
                <div class="scTable-pagination">
                    <el-pagination
                        v-if="!hidePagination"
                        background
                        :small="true"
                        :layout="paginationLayout"
                        :total="total"
                        :page-size="scPageSize"
                        :page-sizes="pageSizes"
                        v-model:currentPage="currentPage"
                        @current-change="paginationChange"
                        @update:page-size="pageSizeChange"
                    ></el-pagination>
                </div>
                <div class="scTable-do" v-if="!hideDo">
                    <el-button
                        v-if="!hideRefresh"
                        @click="refresh"
                        icon="el-icon-refresh"
                        circle
                        style="margin-left: 15px"
                    ></el-button>
                    <el-popover
                        v-if="column"
                        placement="top"
                        title="列设置"
                        :width="500"
                        trigger="click"
                        :hide-after="0"
                        @show="customColumnShow = true"
                        @after-leave="customColumnShow = false"
                    >
                        <template #reference>
                            <el-button icon="el-icon-set-up" circle style="margin-left: 15px"></el-button>
                        </template>
                        <columnSetting
                            v-if="customColumnShow"
                            ref="columnSetting"
                            @userChange="columnSettingChange"
                            @save="columnSettingSave"
                            @back="columnSettingBack"
                            :column="userColumn"
                        ></columnSetting>
                    </el-popover>
                    <el-popover
                        v-if="!hideSetting"
                        placement="top"
                        title="表格设置"
                        :width="400"
                        trigger="click"
                        :hide-after="0"
                    >
                        <template #reference>
                            <el-button icon="el-icon-setting" circle style="margin-left: 15px"></el-button>
                        </template>
                        <el-form label-width="80px" label-position="left">
                            <el-form-item label="表格尺寸">
                                <el-radio-group
                                    v-model="config.size"
                                    size="small"
                                    @change="configSizeChange"
                                >
                                    <el-radio-button label="large">大</el-radio-button>
                                    <el-radio-button label="default">正常</el-radio-button>
                                    <el-radio-button label="small">小</el-radio-button>
                                </el-radio-group>
                            </el-form-item>
                            <el-form-item label="样式">
                                <el-checkbox v-model="config.border" label="纵向边框"></el-checkbox>
                                <el-checkbox v-model="config.stripe" label="斑马纹"></el-checkbox>
                            </el-form-item>
                        </el-form>
                    </el-popover>
                </div>
            </div>
        </div>
        <div v-else class="scTable-table" :style="{ height: _table_height }">
            <el-table
                v-bind="$attrs"
                :data="form.tableData"
                :rules="rules"
                :row-key="rowKey"
                :key="toggleIndex"
                ref="scTable"
                :height="height == 'auto' ? null : '100%'"
                :size="config.size"
                :border="config.border"
                :stripe="config.stripe"
                :summary-method="
					remoteSummary ? remoteSummaryMethod : summaryMethod
				"
                @sort-change="sortChange"
                @filter-change="filterChange"
            >
                <slot></slot>
                <template v-for="(item, index) in userColumn" :key="index">
                    <el-table-column
                        v-if="!item.hide && showColumn"
                        :column-key="item.prop"
                        :label="item.label"
                        :prop="item.prop"
                        :width="item.width"
                        :sortable="item.sortable"
                        :fixed="item.fixed"
                        :filters="item.filters"
                        :filter-method="
							remoteFilter || !item.filters ? null : filterHandler
						"
                        :show-overflow-tooltip="item.showOverflowTooltip"
                    >
                        <template #default="scope">
                            <slot :name="item.prop" v-bind="scope">{{ scope.row[item.prop] }}</slot>
                        </template>
                    </el-table-column>
                </template>
                <el-table-column min-width="1"></el-table-column>
                <template #empty>
                    <el-empty :description="emptyText" :image-size="100"></el-empty>
                </template>
            </el-table>
            <div class="scTable-page" v-if="!hidePagination || !hideDo">
                <div class="scTable-pagination">
                    <el-pagination
                        v-if="!hidePagination"
                        background
                        :small="true"
                        :layout="paginationLayout"
                        :total="total"
                        :page-size="scPageSize"
                        :page-sizes="pageSizes"
                        v-model:currentPage="currentPage"
                        @current-change="paginationChange"
                        @update:page-size="pageSizeChange"
                    ></el-pagination>
                </div>
                <div class="scTable-do" v-if="!hideDo">
                    <el-button
                        v-if="!hideRefresh"
                        @click="refresh"
                        icon="el-icon-refresh"
                        circle
                        style="margin-left: 15px"
                    ></el-button>
                    <el-popover
                        v-if="column"
                        placement="top"
                        title="列设置"
                        :width="500"
                        trigger="click"
                        :hide-after="0"
                        @show="customColumnShow = true"
                        @after-leave="customColumnShow = false"
                    >
                        <template #reference>
                            <el-button icon="el-icon-set-up" circle style="margin-left: 15px"></el-button>
                        </template>
                        <columnSetting
                            v-if="customColumnShow"
                            ref="columnSetting"
                            @userChange="columnSettingChange"
                            @save="columnSettingSave"
                            @back="columnSettingBack"
                            :column="userColumn"
                        ></columnSetting>
                    </el-popover>
                    <el-popover
                        v-if="!hideSetting"
                        placement="top"
                        title="表格设置"
                        :width="400"
                        trigger="click"
                        :hide-after="0"
                    >
                        <template #reference>
                            <el-button icon="el-icon-setting" circle style="margin-left: 15px"></el-button>
                        </template>
                        <el-form label-width="80px" label-position="left">
                            <el-form-item label="表格尺寸">
                                <el-radio-group
                                    v-model="config.size"
                                    size="small"
                                    @change="configSizeChange"
                                >
                                    <el-radio-button label="large">大</el-radio-button>
                                    <el-radio-button label="default">正常</el-radio-button>
                                    <el-radio-button label="small">小</el-radio-button>
                                </el-radio-group>
                            </el-form-item>
                            <el-form-item label="样式">
                                <el-checkbox v-model="config.border" label="纵向边框"></el-checkbox>
                                <el-checkbox v-model="config.stripe" label="斑马纹"></el-checkbox>
                            </el-form-item>
                        </el-form>
                    </el-popover>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import config from "@/config/table";
import columnSetting from "./columnSetting";
import publicjs from "@/api/model/publicjs";
import TreeUtils from "@/api/model/TreeUtils";
import { set } from "nprogress";
import sortable from "sortablejs";
export default {
    name: "scTable",
    components: {
        columnSetting,
    },
    props: {
        bindType: { type: String, default: "entity" }, //entity默认实体类型sqlquery自定义sql
        tableName: { type: String, default: "" },
        apiObj: { type: Object, default: () => {} },
        params: { type: Object, default: () => ({}) },
        data: { type: Object, default: () => {} },
        dataSummary: { type: Object, default: () => {} },
        totalCount: { type: Object, default: () => {} },
        height: { type: [String, Number], default: "100%" },
        size: { type: String, default: "default" },
        border: { type: Boolean, default: false },
        stripe: { type: Boolean, default: false },
        pageSize: { type: Number, default: config.pageSize },
        // currentIndex:{type: Number, default: 1},
        pageSizes: { type: Array, default: config.pageSizes },
        rowKey: { type: String, default: "" },
        summaryMethod: { type: Function, default: null },
        column: { type: Object, default: () => {} },
        remoteSort: { type: Boolean, default: false },
        remoteFilter: { type: Boolean, default: false },
        remoteSummary: { type: Boolean, default: false },
        hidePagination: { type: Boolean, default: false },
        hideDo: { type: Boolean, default: false },
        hideRefresh: { type: Boolean, default: false },
        hideSetting: { type: Boolean, default: false },
        paginationLayout: { type: String, default: config.paginationLayout },
        //自[],加属性
        // eslint-disable-next-line vue/require-prop-type-constructor
        batchEdit: false,
        rules: {},
        attrList: { type: Object, default: () => {} },
        valueList: { type: Object, default: () => {} },
        queryList: { type: Object, default: () => {} },
        orderList: { type: Object, default: () => {} },
        parentChild: { type: Boolean, default: false },
        queryType: { type: String, default: "query" },
        IsNeedHide: { type: Boolean, default: false },
        showColumn: { type: Boolean, default: true },
        columnDrop: { type: Boolean, default: false },
        isKeyDown: { type: Boolean, default: true },
    },
    watch: {
        //监听从props里拿到值了
        data() {
            this.form.tableData = this.data;
            // this.total = this.form.tableData.length;
        },
        apiObj() {
            this.tableParams = this.params;
            this.refresh();
        },
        dataSummary() {
            this.summary = this.dataSummary;
        },
        totalCount() {
            this.total = this.totalCount;
        },
    },
    computed: {
        _height() {
            return Number(this.height)
                ? Number(this.height) + "px"
                : this.height;
        },
        _table_height() {
            return this.hidePagination && this.hideDo
                ? "100%"
                : "calc(100% - 90px)";
        },
    },
    data() {
        return {
            scPageSize: this.pageSize,
            isActivat: true,
            emptyText: "暂无数据",
            toggleIndex: 0,
            form: { tableData: [] },
            total: 0,
            currentPage: 1,
            prop: null,
            order: null,
            loading: false,
            tableHeight: "100%",
            tableParams: this.params,
            userColumn: [],
            customColumnShow: false,
            summary: {},
            config: {
                size: this.size,
                border: this.border,
                stripe: this.stripe,
            },
        };
    },
    mounted() {
        //判断是否开启自定义列
        if (this.column) {
            this.getCustomColumn();
        } else {
            this.userColumn = this.column;
        }
        //判断是否静态数据
        if (this.apiObj) {
            this.getData();
        } else if (this.data) {
            this.form.tableData = this.data;
            this.total = this.data.length;
        }

        window.addEventListener("keydown", this.keyDown);

        if (this.columnDrop) {
            // 列的拖拽初始化
            this.columnDropInit();
        }
    },
    activated() {
        if (!this.isActivat) {
            this.$refs.scTable.doLayout();
        }
    },
    deactivated() {
        this.isActivat = false;
    },
    methods: {
        //获取列
        async getCustomColumn() {
            const userColumn = await config.columnSettingGet(
                this.tableName,
                this.column
            );
            this.userColumn = userColumn;
        },
        //推送数据的刷新，主要是状态或数量，暂不涉及统计
        pushData(pkName, pkValue, objDta) {
            // eslint-disable-next-line no-debugger
            //debugger;
            this.form.tableData.forEach((row) => {
                if (row[pkName] === pkValue) {
                    for (let att in objDta) row[att] = objDta[att];
                }
            });
        },
        //获取数据
        async getData() {
            this.loading = true;
            if (this.prop && this.order) {
                //var stortStr=this.prop;
                //var stortobj=eval('{'+stortStr+': this.order }')
                this.queryList.OrderByFileds = this.prop + " " + this.order;
            }
            this.queryList.PageIndex = this.currentPage;
            if (!this.IsNeedHide)
                this.queryList.PageSize = this.hidePagination
                    ? "0"
                    : this.scPageSize;
            else this.queryList.PageSize = this.scPageSize;
            try {
                var returnValue = await this.$API.auth.PostProcessApi.post(
                    this.queryType,
                    { ...this.queryList }
                );
                console.log(returnValue);
                if (returnValue) {
                    if (returnValue.status != 200) {
                        this.loading = false;
                        this.$message.error("操作失败:" + returnValue.msg);
                        return false;
                    }
                    //eslint-disable-next-line no-debugger
                    //debugger;
                    this.form.tableData = null;
                    if (this.parentChild) {
                        //处理树状数据
                        let newList =
                            returnValue.Result.Content.ObjectList.Object.Rows
                                .Row;
                        let format = {
                            id: "id", //菜单编号，作为树形查找id
                            root: "00", //顶层节点的parentId是root
                            pid: "parentId", //父节点标识字段为parentId
                            child: "children", //构造出的树形子节点数组名为children
                            sort: { field: "id", direct: 1 },
                        }; //排序字段为sortNo，且正序
                        //eslint-disable-next-line no-debugger
                        //debugger;
                        let result = TreeUtils.treetool.format(newList, format);
                        this.form.tableData = result;
                    } else {
                        this.total =
                            parseInt(returnValue.response.dataCount) || 0;
                        if (this.total > 0) {
                            this.form.tableData = returnValue.response.data;
                            // if (
                            // 	returnValue.Result.Content.ObjectList.Object
                            // 		.sumList
                            // ) {
                            // 	//this.summary ={"DefauleSalePrice":60};
                            // 	this.summary =
                            // 		JSON.parse(
                            // 			returnValue.Result.Content.ObjectList
                            // 				.Object.sumList
                            // 		) || {};
                            // }
                        } else {
                            this.form.tableData = [];
                            this.emptyText = "暂无数据";
                        }
                    }
                }
                //this.summary = response.summary || {};
                this.loading = false;
                console.log("请求返回值：", returnValue.response.data);
                //this.$refs.scTable.setScrollTop(0);
                this.$emit("dataChange", this.form.tableData);
            } catch (error) {
                this.loading = false;
                this.$message.error("操作失败:" + error);
                //this.emptyText = error.statusText;
                return false;
            }
        },
        validate(callback) {
            //这个form是子组件内部 el-form 的 ref="form"
            this.$refs["formTableRef"].validate((valid) => {
                callback(valid);
            });
        },
        //分页点击
        paginationChange(e) {
            if (this.bindType == "entity") {
                this.getData();
            } else console.log(this.scPageSize, this.currentPage);
            this.$emit("prentBind", {
                pageSize: this.scPageSize,
                currentPage: this.currentPage,
            });
        },
        //条数变化
        pageSizeChange(size) {
            console.log('bindType',this.bindType)
            this.scPageSize = size;
            // eslint-disable-next-line no-undef, no-debugger
            if (this.bindType == "entity") {
                this.scPageSize = size;
                this.getData();
            } else {
                this.$emit("prentBind", {
                    pageSize: this.scPageSize,
                    currentPage: this.currentPage,
                });
            }
        },
        //刷新数据
        refresh() {
            // eslint-disable-next-line no-undef, no-debugger
            if (this.bindType == "entity") {
                this.$refs.scTable.clearSelection();
                this.getData();
            } else {
                this.$emit("prentBind", {
                    pageSize: this.scPageSize,
                    currentPage: this.currentPage,
                });
            }
        },
        //更新数据 合并上一次params
        upData(params, page = 1) {
            if (this.bindType == "entity") {
                this.currentPage = page;
                this.$refs.scTable.clearSelection();
                Object.assign(this.tableParams, params || {});
                this.getData();
            } else {
                this.$emit("prentBind", {
                    pageSize: this.scPageSize,
                    currentPage: this.currentPage,
                });
            }
        },
        //重载数据 替换params
        reload(params, page = 1) {
            this.currentPage = page;
            this.tableParams = params || {};
            this.$refs.scTable.clearSelection();
            this.$refs.scTable.clearSort();
            this.$refs.scTable.clearFilter();
            this.getData();
        },
        //自定义变化事件
        columnSettingChange(userColumn) {
            this.userColumn = userColumn;
            this.toggleIndex += 1;
        },
        //自定义列保存
        async columnSettingSave(userColumn) {
            this.$refs.columnSetting.isSave = true;
            try {
                await config.columnSettingSave(this.tableName, userColumn);
            } catch (error) {
                this.$message.error("保存失败");
                this.$refs.columnSetting.isSave = false;
            }
            this.$message.success("保存成功");
            this.$refs.columnSetting.isSave = false;
        },
        //自定义列重置
        async columnSettingBack() {
            this.$refs.columnSetting.isSave = true;
            try {
                const column = await config.columnSettingReset(
                    this.tableName,
                    this.column
                );
                this.userColumn = column;
                this.$refs.columnSetting.usercolumn = JSON.parse(
                    JSON.stringify(this.userColumn || [])
                );
            } catch (error) {
                this.$message.error("重置失败");
                this.$refs.columnSetting.isSave = false;
            }
            this.$refs.columnSetting.isSave = false;
        },
        //排序事件
        sortChange(obj) {
            if (obj.column && obj.prop) {
                this.prop = obj.prop;
                this.order = obj.order == "descending" ? "desc" : "asc";
            } else {
                this.prop = null;
                this.order = null;
            }
            if (this.bindType == "entity") {
                this.getData();
            } else {
                this.$emit("prentBind", {
                    pageSize: this.scPageSize,
                    currentPage: this.currentPage,
                });
            }
        },
        //本地过滤
        filterHandler(value, row, column) {
            const property = column.property;
            return row[property] === value;
        },

        //过滤事件
        filterChange(filters) {
            if (!this.remoteFilter) {
                return false;
            }
            Object.keys(filters).forEach((key) => {
                filters[key] = filters[key].join(",");
            });
            this.upData(filters);
        },
        //远程合计行处理
        remoteSummaryMethod(param) {
            const { columns } = param;
            const sums = [];
            columns.forEach((column, index) => {
                if (index === 0) {
                    sums[index] = "合计";
                    return;
                }
                const values = this.summary[column.property];
                if (values) {
                    sums[index] = values;
                } else {
                    sums[index] = "";
                }
            });
            return sums;
        },
        configSizeChange() {
            this.$refs.scTable.doLayout();
        },
        //插入行 unshiftRow
        unshiftRow(row) {
            this.tableData.unshift(row);
        },
        //插入行 pushRow
        pushRow(row) {
            this.tableData.push(row);
        },
        //根据key覆盖数据
        updateKey(row, rowKey = this.rowKey) {
            this.tableData
                .filter((item) => item[rowKey] === row[rowKey])
                .forEach((item) => {
                    Object.assign(item, row);
                });
        },
        //根据index覆盖数据
        updateIndex(row, index) {
            Object.assign(this.tableData[index], row);
        },
        //根据index删除
        removeIndex(index) {
            this.tableData.splice(index, 1);
        },
        //根据index批量删除
        removeIndexes(indexes = []) {
            indexes.forEach((index) => {
                this.tableData.splice(index, 1);
            });
        },
        //根据key删除
        removeKey(key, rowKey = this.rowKey) {
            this.tableData.splice(
                this.tableData.findIndex((item) => item[rowKey] === key),
                1
            );
        },
        //根据keys批量删除
        removeKeys(keys = [], rowKey = this.rowKey) {
            keys.forEach((key) => {
                this.tableData.splice(
                    this.tableData.findIndex((item) => item[rowKey] === key),
                    1
                );
            });
        },
        //原生方法转发
        clearSelection() {
            this.$refs.scTable.clearSelection();
        },
        toggleRowSelection(row, selected) {
            this.$refs.scTable.toggleRowSelection(row, selected);
        },
        toggleAllSelection() {
            this.$refs.scTable.toggleAllSelection();
        },
        toggleRowExpansion(row, expanded) {
            this.$refs.scTable.toggleRowExpansion(row, expanded);
        },
        setCurrentRow(row) {
            this.$refs.scTable.setCurrentRow(row);
        },
        clearSort() {
            this.$refs.scTable.clearSort();
        },
        clearFilter(columnKey) {
            this.$refs.scTable.clearFilter(columnKey);
        },
        doLayout() {
            this.$refs.scTable.doLayout();
        },
        sort(prop, order) {
            this.$refs.scTable.sort(prop, order);
        },
        // 回车搜索
        keyDown(e) {
            if (this.isKeyDown) {
                var ev = document.all ? window.event : e;
                if (ev.keyCode === 13) {
                    // 搜索事件
                    this.getData();
                }
            }
        },
        //列拖拽
        columnDropInit() {
            const _this = this;
            const wrapperTr = document.querySelector(
                ".el-table__header-wrapper tr"
            );
            sortable.create(wrapperTr, {
                animation: 500,
                delay: 0,
                onUpdate: (event) => {
                    var newIndex = event.newIndex;
                    var oldIndex = event.oldIndex;
                    var div = wrapperTr.children[newIndex];
                    var oldLi = wrapperTr.children[oldIndex];

                    const empty = 1;
                    // 先删除移动的节点
                    wrapperTr.removeChild(div);
                    // 再插入移动的节点到原有节点，还原了移动的操作
                    if (newIndex > oldIndex) {
                        wrapperTr.insertBefore(div, oldLi);
                    } else {
                        wrapperTr.insertBefore(div, oldLi.nextSibling);
                    }
                    // 更新items数组
                    const oldItem = this.column[oldIndex - empty];
                    this.column.splice(oldIndex - empty, 1);
                    this.column.splice(newIndex - empty, 0, oldItem);

                    _this.$nextTick(() => {});
                },
            });
        },
    },
};
</script>

<style scoped>
.scTable {
}

.scTable-table {
    height: calc(100% - 50px);
}

.scTable-page {
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 15px;
}

.scTable-do {
    white-space: nowrap;
}

.scTable:deep(.el-table__footer) .cell {
    font-weight: bold;
}

.scTable:deep(.el-table__body-wrapper) .el-scrollbar__bar.is-horizontal {
    height: 12px;
    border-radius: 12px;
}

.scTable:deep(.el-table__body-wrapper) .el-scrollbar__bar.is-vertical {
    width: 12px;
    border-radius: 12px;
}
</style>
